#include "globalVariables.h"
#include "DataDefine.h"
#include "HitAnimation.h"

Card* getCard(int id);
int gameInitialize();
int stateChanging(int targetState);
void turnChange();
int udpBroadcastReceive(string& message);
int tcpSend(string message);

int dataProcess()
{
	//ai process
	/*if (isSinglePlayer)
	{
		if (!isPlayerTurn)
		{
			if (!isTurnChanging)
			{
				turnChange();
			}
		}
	}*/
	//destroy process
	list<int>::iterator xiter = destroyX.begin(); 
	list<int>::iterator yiter = destroyY.begin();
	for (; xiter != destroyX.end(); xiter++, yiter++)
	{
		delete board[*xiter][*yiter];
		board[*xiter][*yiter] = NULL;
	}
	destroyX.clear();
	destroyY.clear();
	//Animation process
	auto aiter = animationList.begin();
	for (; aiter != animationList.end();)
	{
		(*aiter)->run();
		auto niter = aiter;
		if ((*aiter)->isToDestroy)
		{
			niter++;
			animationList.erase(aiter);
			aiter = niter;
			continue;
		}
		aiter++;
	}
	//fading process
	if (isSceneChanging)
	{
		globalCounter++;
		if (globalCounter == FADEFRAME)
		{
			stateChanging(targetState);
		}
		if (globalCounter >= 2 * FADEFRAME)
		{
			isSceneChanging = false;
			globalCounter = 0;
		}
	}
	//turn change process
	if (isTurnChanging)
	{
		globalCounter++;
		if (globalCounter == 3 * TURNCHANGEFRAME)
		{
			isTurnChanging = false;
			globalCounter = 0;
		}
	}

	//gameover process
	if (isGameOverChanging)
	{
		globalCounter++;
		if (globalCounter == GAMEOVERFRAME)
		{
			isGameOverChanging = false;
			if (gameoverBGTexture)
			{
				SDL_DestroyTexture(gameoverBGTexture);
			}
			//get window content
			Uint32 rmask;
			Uint32 gmask;
			Uint32 bmask;
			Uint32 amask;
			Uint32 format;
			int bpp;
			int pitch;
			format = SDL_GetWindowPixelFormat(window);
			pitch = SDL_BYTESPERPIXEL(format) * WINDOW_WIDTH;
			SDL_RenderReadPixels(renderer, NULL, format, windowPixels, pitch);
			SDL_PixelFormatEnumToMasks(format, &bpp, &rmask, &gmask, &bmask, &amask);
			SDL_Surface* surface = SDL_CreateRGBSurfaceFrom((void*)windowPixels, WINDOW_WIDTH, WINDOW_HEIGHT, bpp, pitch, rmask, gmask, bmask, amask);
			gameoverBGTexture = SDL_CreateTextureFromSurface(renderer, surface);
			SDL_FreeSurface(surface);

			globalCounter = 0;
			stateChanging(GAMEOVER);
		}
	}
	return 0;
}

int netMessageProcess(string message)
{
	char buffer[20];
	int a, b, c, d;
	if (message == "")
	{
		return 0;
	}
	sscanf_s(message.c_str(), "%s", buffer, 20);
	if (!strcmp(buffer, "DECKINIT"))
	{
		isSinglePlayer = false;
		enemyDeck.clear();
		return 0;
	}
	if (!strcmp(buffer, "LINK"))
	{
		tcpSend("DECKINIT ");
		for (Card* c : usingDeck)
		{
			tcpSend("DECK "+to_string(c->id)+" ");
		}
		tcpSend("OK ");
		tcpSend("BEGIN ");
		tcpSend("OK ");
		return 0;
	}
	if (!strcmp(buffer, "DECK"))
	{
		sscanf_s(message.c_str(), "%s%d", buffer, 20, &a);
		enemyDeck.push_back(getCard(a));
		return 0;
	}
	if (!strcmp(buffer, "BEGIN"))
	{
		isSceneChanging = true;
		globalCounter = 0;
		targetState = GAMEPLAYING;
		isSinglePlayer = false;
		gameInitialize();
		return 0;
	}
	if (!strcmp(buffer, "OK"))
	{
		isPlayerInitDone = true;
		return 0;
	}
	if (!strcmp(buffer, "DRAW"))
	{
		sscanf_s(message.c_str(), "%s%d", buffer, 20, &a);
		enemyPlayer->draw(a);
		return 0;
	}
	if (!strcmp(buffer, "SURRENDER"))
	{
		enemyPlayer->damage(enemyPlayer->health);
		return 0;
	}
	if (!strcmp(buffer, "TURNCHANGE"))
	{
		if (globalState == GAMEPLAYING && !isSceneChanging)
		{
			turnChange();
		}
		return 0;
	}
	if (!strcmp(buffer, "DIRECT"))
	{
		sscanf_s(message.c_str(), "%s%d", buffer, 20, &a);
		player->damage(a);
		return 0;
	}
	if (!strcmp(buffer, "ACT"))
	{
		sscanf_s(message.c_str(), "%s%d%d%d", buffer, 20, &a, &b, &c);
		enemySelectedCard = enemyPlayer->handcard.begin();
		for (; enemySelectedCard != enemyPlayer->handcard.end(); enemySelectedCard++)
		{
			if ((*enemySelectedCard)->card->id == a)
			{
				break;
			}
		}
		(*enemySelectedCard)->card->enemyActivate(6 - b, 8 - c);
		return 0;
	}
	if (!strcmp(buffer, "MOVE"))
	{
		sscanf_s(message.c_str(), "%s%d%d%d%d", buffer, 20, &a, &b, &c, &d);
		board[6 - a][8 - b] = board[6 - c][8 - d];
		board[6 - a][8 - b]->xPos = 6 - a;
		board[6 - a][8 - b]->yPos = 8 - b;
		board[6 - a][8 - b]->hasMoved = true;
		board[6 - c][8 - d] = NULL;
		return 0;
	}
	if (!strcmp(buffer, "DAMAGE"))
	{
		sscanf_s(message.c_str(), "%s%d%d%d", buffer, 20, &a, &b, &c);
		board[6 - a][8 - b]->damage(c);
		return 0;
	}
}

int stateChanging(int targetState)
{
	globalState = targetState;
	switch (targetState)
	{
	case MAINMENU:
		currentButtonList = &mainmenuButtonList;
		break;
	case GAMEPLAYING:
		currentButtonList = &gameplayingButtonList;
		break;
	case GAMEOVER:
		currentButtonList = &gameoverButtonList;
		break;
	case NETPROCESS:
		currentButtonList = &netprocessButtonList;
		break;
	case DECKEDIT:
		currentButtonList = &deckeditButtonList;
		break;
	case ABOUT:
		currentButtonList = &aboutButtonList;
		break;
	}
	return 0;
}

void turnChange()
{
	isPlayerTurn = !isPlayerTurn;
	isSelecting = false;
	mapSelectBuffer = false;
	for (Handcard* hcptr : player->handcard)
	{
		hcptr->release();
	}
	//animation
	globalCounter = 0;
	isTurnChanging = true;
	//cost increase
	if (isPlayerTurn)
	{
		player->turnCost++;
		if (player->turnCost > MAX_COST)
		{
			player->turnCost = MAX_COST;
		}
		player->currentCost = player->turnCost;
		int a = player->draw();
		if (!isSinglePlayer)
		{
			tcpSend("DRAW " + to_string(a) + " ");
		}
	}
	else
	{
		enemyPlayer->turnCost++;
		if (enemyPlayer->turnCost > MAX_COST)
		{
			enemyPlayer->turnCost = MAX_COST;
		}
		enemyPlayer->currentCost = enemyPlayer->turnCost;
		if (isSinglePlayer)
		{
			enemyPlayer->draw();
		}
	}
	//checker reset
	if (isPlayerTurn)
	{
		for (int i = 0; i < 7; i++)
		{
			for (int j = 0; j < 9; j++)
			{
				if (board[i][j] && !board[i][j]->isEnemy)
				{
					if (board[i][j]->isFrozen)
					{
						board[i][j]->isFrozen = false;
					}
					else
					{
						board[i][j]->hasMoved = false;
					}
				}
			}
		}
	}
	else
	{
		for (int i = 0; i < 7; i++)
		{
			for (int j = 0; j < 9; j++)
			{
				if (board[i][j] && board[i][j]->isEnemy)
				{
					if (board[i][j]->isFrozen)
					{
						board[i][j]->isFrozen = false;
					}
					else
					{
						board[i][j]->hasMoved = false;
					}
				}
			}
		}
	}
}